import { App } from "../App";

/**
 * 如果异性精灵有叠加的情况，需要添加PolygonCollider组件，并且勾勒出精灵的轮廓
 */
const { menu, ccclass, property } = cc._decorator;
@ccclass
@menu("自定义插件/控件点击音效")
export default class TouchNode extends cc.Component {
    @property({ tooltip: 'i18n:COMPONENT.button.interactable', animatable: false })
    interactable: boolean = true;
    @property({tooltip: '点击播放音效文件，优先级最低与AudioClip属性互斥'})
    audioFile: string = 'click';
    @property({ type: cc.AudioClip, tooltip: '点击播放音效文件,优先级最高与AudioFile属性互斥' })
    audioClip: cc.AudioClip = null;
    @property({ type: cc.Node, tooltip: '点击点击后隐藏节点.注意：会从父节点移除' })
    hideNode: cc.Node = null;
    @property({ tooltip: '点击缩放' })
    zoomScale: number = 1.1;
    @property({ range: [0, 10], tooltip: '缩放效果持续时间' })
    duration: number = 0.1;
    @property({ type: cc.Component.EventHandler, tooltip: '点击响应事件' })
    clickEvent: cc.Component.EventHandler = null;


    private _scale: number = 1;
    private _pressed: boolean = false;
    private _touchPoints: cc.Vec2[] = [];
    private _isNeedCollider: boolean = false;
    private _isCanTouch:boolean = true;
    private _isCancel:boolean = false;

    onLoad() {
        this._scale = this.node.scale;
        this.node.on(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
        if (this.node.getComponent(cc.PolygonCollider)) {
            this._isNeedCollider = true;
            let _pos: cc.Vec2[] = this.node.getComponent(cc.PolygonCollider).points;
            for (let i = 0; i < _pos.length; ++i) {
                this._touchPoints[i] = _pos[i].add(this.node.convertToWorldSpaceAR(cc.Vec2.ZERO_R)).mul(this._scale);
            }
        }
        if (!this.audioClip){
            App.Res.loadResources(this.audioFile,cc.AudioClip,(clip:cc.AudioClip)=>{
                this.audioClip = clip;
            });
        }
    }

    onDestroy() {
        this.node.off(cc.Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.off(cc.Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.off(cc.Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    };

    private onTouchStart(touch: cc.Event.EventTouch) {
        if (!this._pressed && this.interactable && this._isCanTouch) {
            this._isCanTouch = false;
            if (this._isNeedCollider) {
                if (cc.Intersection.pointInPolygon(touch.getLocation(), this._touchPoints)) {
                    // @ts-ignore
                    this.node._touchListener.setSwallowTouches(true);
                    this._pressed = true;
                } else {
                    // @ts-ignore
                    this.node._touchListener.setSwallowTouches(false);
                    this._pressed = false;
                }
            } else this._pressed = true;

            if (this._pressed){
                cc.tween(this.node).stop();
                cc.tween(this.node).to(this.duration,{scale:this.zoomScale})
                .call(()=>{
                    this.audioClip && App.Audio.play(this.audioClip);
                }).start();
            }
        }
    };

    private onTouchEnd(touch: cc.Event.EventTouch) {
        if (this.node !== touch.target || !this._pressed || !this.interactable) return ;

        cc.tween(this.node).stop();
        cc.tween(this.node).to(this.duration,{scale:this._scale})
        .call(()=>{
            if (!this._isCancel){
                this.clickEvent && cc.Component.EventHandler.emitEvents([this.clickEvent], touch);
                this.hideNode && cc.tween(this.hideNode).to(this.duration,{scale:0},{easing:'quadIn'})
                .call(()=>{
                    App.closeView(this.hideNode);
                }).start();
            }
        }).call(()=>{
            this._pressed = false;
            this._isCancel = false;
            this._isCanTouch = true;
        }).start();
    }
    private onTouchCancel(touch: cc.Event.EventTouch) {
        this._isCancel = true;
        this.onTouchEnd(touch);
    }
}
